import { useEffect, useRef, useState } from 'react'
import './GeSelectModal.scss'
import RemoveSvg from '@/svg/RemoveSvg'
import useStateRef from '@/hooks/useStateRef'
import imageLoadManager from '@/lib/imageLoadManager'
import { loadImageInfo } from '@/utils/loadVideo'
import { showLoading } from '@/utils/loading'
import { Color } from '@/lib/Color'
import { imageFilter } from '@/lib/imageFilter'
import useNumInput from '@/hooks/useNumInput'
import { showContextMenu } from '@/utils/contextMenu'
import CustomCanvas from '@/component/CustomCanvas'
import { useI18n } from '@/i18n'
interface Props {
  show: boolean
  onHide: () => void
  allFrameList: FrameInfo[]
  fps: number
  onUpdate: (frameList: string[]) => void
}

const GeSelectModal = ({
  show,
  onHide,
  allFrameList,
  fps,
  onUpdate,
}: Props) => {
  const { t } = useI18n()
  const canvasRef = useRef<HTMLCanvasElement>(null)
  const frameTextRef = useRef<HTMLSpanElement>(null)
  const imageFrameList = useRef<HTMLImageElement[]>([])
  const canvasCtx = useRef<CanvasRenderingContext2D | null>(null)
  const [canvasSize, setCanvasSize, canvasSizeRef] = useStateRef({
    width: 200,
    height: 200,
  })
  const [size, setSize, sizeStr, onSizeBlur] = useNumInput(1, {
    min: 1,
    int: true,
    max: 300,
  })
  const [step, setStep, stepStr, onStepBlur] = useNumInput(1, {
    min: 0,
    int: true,
    max: 300,
  })
  const [frameList, setFrameList] = useState<FrameInfo[]>([])

  useEffect(() => {
    const list: FrameInfo[] = []
    for (let i = 0; i < allFrameList.length; i += step) {
      for (let j = 0; j < size; j++) {
        if (i + j >= allFrameList.length) break
        list.push(allFrameList[i + j])
      }
      i += size
    }
    setFrameList(list)
  }, [allFrameList, step, size])
  useEffect(() => {
    const task = async () => {
      if (frameList.length != 0) {
        const info = await loadImageInfo(frameList[0].url)
        setCanvasSize({
          width: info.width,
          height: info.height,
        })
        canvasRef.current.width = info.width
        canvasRef.current.height = info.height
      } else {
        setCanvasSize({ width: 200, height: 200 })
        canvasRef.current.width = 200
        canvasRef.current.height = 200
      }
    }
    task()
  }, [frameList])
  useEffect(() => {
    if (!show) {
      return
    }
    let isEnd = false
    const task = async () => {
      imageFrameList.current = await imageLoadManager.loadImageList(frameList)
      //   if (!play) {
      //     return
      //   }
      // 帧时间
      const frameTime = 1000 / fps
      let frame = 0
      let nowframeTime = 0
      let lastTime = 0
      canvasCtx.current = canvasRef.current.getContext('2d')
      canvasCtx.current.imageSmoothingEnabled = false
      const anim = (nowTime: number) => {
        const deltaTime = nowTime - lastTime
        lastTime = nowTime
        nowframeTime += deltaTime
        const addFrame = Math.floor(nowframeTime / frameTime)
        nowframeTime = nowframeTime % frameTime
        draw(frame)
        frame += addFrame
        if (frameList.length == 0) isEnd = true
        while (frame >= frameList.length && frameList.length != 0) {
          frame -= frameList.length
        }
        if (isEnd) return
        requestAnimationFrame(anim)
      }
      requestAnimationFrame(anim)
    }
    task()
    return () => {
      isEnd = true
    }
  }, [show, frameList, canvasSize])

  const draw = (frame = 0) => {
    if (frame < 0 || frame >= imageFrameList.current.length) {
      return
    }
    const ctx = canvasCtx.current
    if (!ctx) return
    const w = canvasSizeRef.current.width
    const h = canvasSizeRef.current.height
    ctx.clearRect(0, 0, w, h)
    if (frameList.length == 0) {
      return
    }
    const imageW = imageFrameList.current[frame].naturalWidth
    const imageH = imageFrameList.current[frame].naturalHeight
    ctx.drawImage(
      imageFrameList.current[frame],
      0,
      0,
      imageW,
      imageH,
      0,
      0,
      w,
      h
    )
    frameTextRef.current.innerText = `${frame + 1}/${frameList.length}`
  }

  async function onSave(): Promise<void> {
    onUpdate(frameList.map((item) => item.url))
  }

  return (
    <div className="GeSelectModal-component">
      <div className={`GeSelectModal ${show ? 'show' : ''}`}>
        <div className="top">
          <div className="title">
            <span>{t('separateSelection')}</span>
          </div>
          <ripple-button className="remove" onClick={onHide}>
            <RemoveSvg />
          </ripple-button>
        </div>
        <div className="center-box">
          <div className="canvas-view">
            <CustomCanvas className="canvas" ref={canvasRef}></CustomCanvas>
          </div>
          <div className="input-box">
            <div className="label">{t('frame')}</div>
            <div className="value">
              <span ref={frameTextRef}>0/0</span>
            </div>
          </div>
          <div className="input-box">
            <span>{t('partition')}</span>
            <input
              type="number"
              style={{
                width: 60,
              }}
              min={0}
              className="input"
              value={stepStr}
              onChange={(e) => setStep(e.target.value)}
              onBlur={onStepBlur}
            />
            <span>{t('select')}</span>
            <input
              type="number"
              style={{
                width: 60,
              }}
              min={1}
              className="input"
              value={sizeStr}
              onChange={(e) => setSize(e.target.value)}
              onBlur={onSizeBlur}
            />
          </div>
        </div>
        <ripple-button
          style={{
            marginLeft: 'auto',
            background: 'var(--primary-color)',
            color: 'white',
            width: 'fit-content',
            padding: '8px 10px',
          }}
          onClick={onSave}>
          {t('save')}
        </ripple-button>
      </div>
      <div className={`mask ${show ? 'show' : ''}`} onClick={onHide}></div>
    </div>
  )
}

export default GeSelectModal
